package cn.aoyu.test;

import cn.aoyu.test.bean.user.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @ClassName: TestDemo
 * @Auther: xww
 * @Date: 2019/5/15 0015 11:17
 * @Description:
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:myTest.xml")
public class SpringSimpleXmlTestDemo {

	@Test
	public void testDemo() {
		// xml 解析
		xmlTest();
		// applicationContext 解析
		applicationTest();
	}

	/**
	 * applicationContext 解析
	 */
	private void applicationTest() {
		// ApplicationContext中做了new ClassPathResource("myTest.xml")等价的操作返回一个Resource对象
		// 这一步解析xml中的bean，定义为BeanDefinitions,也就是GenericBeanDefinition类，放入Map中去，然后调用getBean的方法去实例化该bean放入到this.singletonObjects。
		// 所以说ApplicationContext原则已经去调用了getBean()这一方法了，所以该实例才会在容器中，
		// getBean方法实际上就是  实例化 -->  将实例化后放入this.singletonObjects这一个map容器中
		/**
		 * @see org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean(String, Class, Object[], boolean) 方法中调用getSingleton(...)
		 *
		 * //	sharedInstance = getSingleton(beanName, () -> {
		 * //		try {
		 * //			return createBean(beanName, mbd, args);
		 * //		} catch (BeansException ex) {
		 * //			.....
		 * //		}
		 * //	});
		 *
		 * 去将实例化的bean加入到
		 * @see org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton(String, Object)    singletonObjects的map中
		 */
		ApplicationContext context = new ClassPathXmlApplicationContext("myTest.xml");
		// 由于上一步已经实例化了bean，这里的getBean实际上已经在spring容器中已经存在了，所以直接去AbstractBeanFactory.doGetBean(){
		//     ........这里是其他代码
		//     直接拿就是了
		// 	   Object sharedInstance = getSingleton(beanName);
		//     ........这里是其他代码
		// }
		User user = (User) context.getBean("user");
		System.out.println("application:" + user.toString());
	}

	/**
	 * xml 解析
	 */
	private static void xmlTest() {
		// 这一步解析xml中的bean，定义为BeanDefinitions，也就是GenericBeanDefinition类，放入Map中去，这里并没有去实例化bean
		BeanFactory bf = new XmlBeanFactory(new ClassPathResource("myTest.xml"));
		// 只有到这一步的时候才回去实例化bean去拿出来,这是和ApplicationContext不一样的地方，XmlBeanFactory采用了延迟加载，在调用getBean的时候才会去创建容器
		User user = (User) bf.getBean("user");
		System.out.println("xml:" + user.toString());
	}

}
